#!/usr/bin/perl
#
# Recalculate the usercount of a place record
#
use strict;
use Counter;
use Fcntl;
use Getopt::Long;

use vars qw($places $persons $key $rec $recursive $getall %counts %subcounts $usage $cleanrec $dowrite $comparemethods $usepatch $DEBUG);

$DEBUG = 0;
$dowrite = 1;
$comparemethods = 0;
$usage = "Usage: $0 [-r] [-d] key\n";

$places = FileTable::open("db/places", O_RDWR);
$persons = FileTable::open("db/persons");

GetOptions(
"recursive" => \$recursive,
"all" => \$getall,
"debug+" => \$DEBUG,
"write!" => \$dowrite,
"compare" => \$comparemethods,
"usepatch" => \$usepatch,
	   );


#while ($ARGV[0] =~ /^-/) {
#    my $opt = shift;
#    if ($opt eq "-r") {
#	$recursive = 1;
#    } elsif ($opt eq "-a") {
#	$getall = 1;
#    } elsif ($opt eq "-d") {
#	++ $DEBUG;
#    } elsif ($opt eq "-n") {
#	$dowrite = 0;
#    } else {
#	die $usage;
#    }
#}

$key = shift;
if ($key =~ /^\d+$/) {
    $rec = $places->get($key);
} else {
    $rec = $places->getbykey("name", $key);
}
die "No such record as $key\n" if !$rec;

# fix a bug introduced by cleaning of the placefile....
$cleanrec = $places->getclean($rec->key());


if ($getall) {
    print STDERR "Getting counts for all in the DB....";
    %counts = $persons->counts("placeid");
    %subcounts = $places->counts("within");
    print STDERR "Got them\n";
    $DEBUG && warn "Got ", keys(%counts) + 0, " counts, ", keys(%subcounts) + 0,
    " subcounts\n";
}

recount($cleanrec);

sub recount {
    my $rec = shift;
    my $herecount;
    $DEBUG && warn "Counting ", $rec->{name}, "\n";
    if ($getall) {
	$herecount = $counts{"\L$$rec{name}"};
	if ($comparemethods) {
	    my $alsoherecount = $persons->count("placeid = ?", $rec->{name});
	    $DEBUG && warn "Comparing for $$rec{name}\n";
	    if ($herecount != $alsoherecount) {
		die "Difference in methods: $$rec{name} - $herecount by getall, $alsoherecount direct\n";
	    }
	}
    } else {
	$herecount = $persons->count("placeid = ?", $rec->{name});
    }

    my $subcount = 0;
    my $reckey = $rec->key();
    if (!$getall || $subcounts{"\L$reckey"}) {
	my @subs = $places->selectclean("within = ? order by name", $rec->key);
	$DEBUG > 1 && warn @subs + 0, " subplaces\n";
	my $sub;
	for $sub (@subs) {
	    next if $sub->{type} eq "alias";
	    if ($recursive) {
		recount($sub);
	    }
	    $subcount += $sub->{users};
	}
    }

#    if ($count1 != $herecount + $subcount) {
#	warn "$$rec{name}: Count1 = $count1 herecount $herecount subcount $subcount\n";
#    }
    my $newcount = $herecount + $subcount;
    if ($newcount != $$rec{users}) {
	warn "$$rec{name}: Changing count from $$rec{users} to $newcount\n";
	# since rec is clean, it's not storable
	my $patchable = $places->get($rec->key());
	$$patchable{users} = $newcount;
	if ($usepatch) {
	    $patchable->patch() if $dowrite; # don't cause a log entry
	} else {
	    $patchable->store() if $dowrite;
	}
	# Also change the record we were called on, to signal
	$$rec{users} = $newcount;
    } else {
	$DEBUG && warn "Count for $$rec{name} is correct at $newcount\n";
    }
}
